package com.google.code.mergeinformer.util.synchronization;

import java.util.Objects;

/**
 * @author Dmitry Golubev
 */
public class Mutex<K, O> {

    private final K key;
    private final O[] operations;

    @SafeVarargs
    Mutex(K key, O... operations) {
        this.key = key;
        this.operations = operations;
    }

    private boolean intersects(O[] first, O[] second) {
        for (Object object1 : first) {
            for (Object object2 : second) {
                if (Objects.equals(object1, object2)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Mutexes are equal if their keys are equal and their operation arrays contain at least one common element.
     * <p/>
     * <b>NOTE:</b> if no operation are specified, mutex is considered to be equal to all other mutexes with the same key,
     * i.e. it synchronizes all operations on particular object.
     * @param o
     * @return
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(this.getClass().equals(o.getClass()))) {
            return false;
        }
        final Mutex<K, O> that = (Mutex<K, O>) o;
        return Objects.equals(key, that.key)
                && (operations == null || operations.length == 0 || that.operations == null || that.operations.length == 0
                || intersects(operations, that.operations));
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(key);
    }
}
